<script setup lang="ts">
import { computed, reactive, ref, toRaw } from "vue";
import { onLoad, onReachBottom, onUnload } from "@dcloudio/uni-app";
import { useList } from "@/hooks/page";
import { usePageScroll } from "@/hooks/scroll";
import {
  note_header_api,
  note_list_api,
  user_follow_api,
} from "@/package/my/api/guider_didi";
import { note_info_api, common_like_api } from "@/api/guider_didi";
import { data_api } from "@/api/my";
import { EV_NOTE, EV_USER } from "@/constant/event";
import { Account } from "@/utils/account";
import { AppData } from "@/utils/app";
import { Window } from "@/utils/window";
import { createWaterfall } from "@/utils/waterfall";
import { Router } from "@/utils/router";
import { Toast } from "@/utils/toast";

import NavBack from "@/components/nav/back.vue";
import NavBg from "@/components/nav/bg.vue";
import NavSpace from "@/components/nav/space.vue";
import PageSticky from "@/components/page/sticky.vue";
import IndexTypeItem from "./components/index-type-item.vue";
import ListEmpty from "@/components/list/empty.vue";
import CommunityNoteItem from "@/pages/index/components/community-note-item.vue";
import CommunityNoteLike from "@/pages/index/components/community-note-like.vue";
import ListMore from "@/components/list/more.vue";
import CommunityNoteBtn from "@/pages/index/components/community-note-btn.vue";
import CommunityNotePicker from "@/pages/index/components/community-note-picker.vue";

onLoad((options) => {
  const _userData = AppData.userData;
  userData.third_img = _userData.third_img;
  userData.nick_name = _userData.nick_name;

  if (options?.id) {
    queryData.uid = options.id;
  } else {
    // 自己查看时没有id
    typeList.value.push("赞过");
  }

  note_header_api({ uid: queryData.uid }).then((resp) => {
    userData.third_img = resp.head_img;
    userData.nick_name = resp.nick_name;
    userData.autograph = resp.autograph;
    numData.follow_count = resp.follow_count;
    numData.fans_count = resp.fans_count;
    numData.like_count = resp.like_count;
  });

  reloadList();

  Account.isLogin && reloadMyData();
  uni.$on(EV_NOTE, evNoteCallback);
  uni.$on(EV_USER, evUserCallback);
});
const { pageIsScroll, onPageScroll } = usePageScroll(() => {
  listLoadMore.value = listData.value.length > 1;
});
onReachBottom(() => loadMoreList());
onUnload(() => {
  uni.$off(EV_NOTE, evNoteCallback);
  uni.$off(EV_USER, evUserCallback);
});

const userData = reactive({ third_img: "", nick_name: "", autograph: "" });

const introClick = () => {
  Router.navigateTo("/package/my/pages/info/edit", (resp) => {
    resp.eventChannel.emit("ev-info-data", {
      key: "autograph",
      value: userData.autograph,
    });
    resp.eventChannel.once("ev-info-data", (resp) => {
      if (resp) {
        userData.autograph = resp;
        Router.navigateBack();
      }
    });
  });
};

const numData = reactive({ follow_count: "", fans_count: "", like_count: "" });
const numClick = (url: string) => {
  queryData.uid ? Toast.show("此功能仅作者本人可见") : Router.navigateTo(url);
};

const queryData = reactive({ uid: "", type: 1, status: -1 });

const typeList = ref(["笔记", "收藏"]);
const typeClick = (id: number) => {
  queryData.type = id;
  reloadList();
};

const stateList = ref([
  { id: -1, name: "全部" },
  { id: 0, name: "未审核" },
  { id: 2, name: "审核不通过" },
]);
const stateClick = (id: number) => {
  queryData.status = id;
  reloadList();
};

const noteList = computed(() => {
  return createWaterfall(
    listData.value.map((i) => {
      if (i.type === 3) {
        Object.assign(i, { img_width: 200, img_height: 290 });
      }
      return i;
    }),
    {
      baseWidth: Window.rpxToPx(336),
      columnHeight: [0, 0],
      widthKey: "img_width",
      heightKey: "img_height",
    }
  );
});
const noteClick = (index: number, index2: number) => {
  if (index === -1) {
    communityNotePicker.value?.show((type, filePath) => {
      Router.navigateTo(
        `/package/guider/pages/note/edit?${Router.dataToQuery({
          type,
          filePath,
        })}`
      );
    });
  } else {
    const note = noteList.value.columnData[index][index2] as any;
    Router.navigateTo(
      note.type === 2
        ? `/package/guider/pages/note/detail2?id=${note.id}`
        : `/package/guider/pages/note/detail?id=${note.id}`
    );
  }
};

const { listData, listStatus, listLoadMore, reloadList, loadMoreList } =
  useList({ page: 1, page_size: 10 }, (query) => {
    return note_list_api({ ...query, ...toRaw(queryData) }).then((resp) => {
      if (!queryData.uid && queryData.type === 1) {
        stateList.value[0].name = `全部 ${resp.statistics.all_count}`;
        stateList.value[1].name = `未审核 ${resp.statistics.to_audit_count}`;
        stateList.value[2].name = `审核不通过 ${resp.statistics.no_audit_count}`;
      }
      return resp;
    });
  });

const myData = reactive({ isFollow: false });
const myDataLikeList = ref<number[]>([]);
const followClick = () => {
  const fn = () => {
    myData.isFollow = !myData.isFollow;
    user_follow_api({ follow_id: queryData.uid, type: 3 }).then(() => {
      uni.$emit(EV_USER, { type: "follow", data: { id: queryData.uid } });
    });
  };

  Account.isLogin
    ? fn()
    : Account.login(() => {
        reloadMyData().then(() => {
          // 没有关注，则关注
          myData.isFollow || fn();
        });
      });
};
const likeClick = (id: number) => {
  const fn = () => {
    const index = myDataLikeList.value.indexOf(id);
    index === -1
      ? myDataLikeList.value.push(id)
      : myDataLikeList.value.splice(index, 1);
    common_like_api({ id, type: 2 }).then(() => {
      uni.$emit(EV_NOTE, { type: "like", data: { type: "guider", id } });
    });
  };

  Account.isLogin
    ? fn()
    : Account.login(() => {
        reloadMyData().then(() => {
          // 没有点赞，则点赞
          myDataLikeList.value.includes(id) || fn();
        });
        Router.navigateBack();
      });
};

const reloadMyData = () => {
  return data_api<{
    guide_share_note_like?: number[];
    note_author_follow?: number[];
  }>({
    includes: "guide_share_note_like,note_author_follow",
  }).then((resp) => {
    myDataLikeList.value = resp.guide_share_note_like || [];
    myData.isFollow = (resp.note_author_follow || []).includes(
      Number(queryData.uid)
    );
  });
};
const evNoteCallback = (e: {
  type: "like";
  data: { type: "guider"; id: number };
}) => {
  console.info(`触发事件：${EV_NOTE}`, e);
  if (e.type === "like" && e.data.type === "guider") {
    // 刷新状态
    reloadMyData();
    // 刷新数字
    note_info_api({ id: `${e.data.id}` }).then((resp) => {
      const index = listData.value.findIndex((i) => i.id === resp.id);
      listData.value[index].like_count_str = resp.like_count_str;
    });
    // 刷新数字
    note_header_api({ uid: queryData.uid }).then((resp) => {
      numData.like_count = resp.like_count;
    });
  }
};
const evUserCallback = (e: { type: "follow" }) => {
  console.info(`触发事件：${EV_USER}`, e);
  if (e.type === "follow") {
    reloadMyData();
    // 刷新数字
    note_header_api({ uid: queryData.uid }).then((resp) => {
      numData.follow_count = resp.follow_count;
      numData.fans_count = resp.fans_count;
    });
  }
};

const communityNotePicker = ref<InstanceType<typeof CommunityNotePicker>>();
</script>

<template>
  <NavBack />
  <NavBg :retract="pageIsScroll">
    <view class="index-bg">
      <image class="index-bg-img" :src="userData.third_img" mode="aspectFill" />
      <view class="index-bg-cover"></view>
    </view>
  </NavBg>
  <NavSpace />

  <view class="index-info">
    <image
      class="index-info-avatar"
      :src="userData.third_img"
      mode="aspectFill"
    />
    <view class="index-info-name">{{ userData.nick_name }}</view>
    <view class="index-info-intro">
      <view class="index-info-intro2">{{ userData.autograph }}</view>
      <image
        class="index-info-intro3"
        v-if="!queryData.uid"
        src="@/package/my/static/note-index-edit.png"
        @click="introClick"
      />
    </view>
    <view style="display: flex; justify-content: center">
      <view
        class="index-info-item"
        @click="numClick('/package/my/pages/follow/list')"
      >
        <view class="index-info-num">{{ numData.follow_count }}</view>
        <view class="index-info-text">关注</view>
      </view>
      <view
        class="index-info-item"
        @click="numClick('/package/my/pages/follow/list?type=1')"
      >
        <view class="index-info-num">{{ numData.fans_count }}</view>
        <view class="index-info-text">粉丝</view>
      </view>
      <view class="index-info-item">
        <view class="index-info-num">{{ numData.like_count }}</view>
        <view class="index-info-text">获赞</view>
      </view>
    </view>

    <view
      class="index-info-follow"
      v-if="queryData.uid"
      :style="{ opacity: myData.isFollow ? 0.4 : '' }"
      @click="followClick"
    >
      {{ myData.isFollow ? "已" : "" }}关注
    </view>
  </view>

  <PageSticky customNav>
    <view class="index-type">
      <view
        class="index-type-item"
        v-for="(i, d) of typeList"
        :key="d"
        @click="typeClick(d + 1)"
      >
        <IndexTypeItem :text="i" :isActive="queryData.type === d + 1" />
      </view>
    </view>
    <view class="index-state" v-if="!queryData.uid && queryData.type === 1">
      <view
        class="index-state-item"
        :class="{ 'index-state-active': queryData.status === i.id }"
        v-for="i of stateList"
        :key="i.id"
        @click="stateClick(i.id)"
      >
        {{ i.name }}
      </view>
    </view>
  </PageSticky>

  <view class="index-data">
    <view
      class="index-data-empty"
      v-if="listData.length === 0 && listStatus === 'noMore'"
    >
      <ListEmpty translateY="0" />
    </view>
    <template v-else>
      <view class="index-data-wrapper">
        <view
          class="index-data-column"
          v-for="(i, d) of noteList.columnData"
          :key="d"
          :style="{ width: `${noteList.columnWidth}px` }"
        >
          <view
            class="index-data-item"
            v-for="(j, x) of i"
            :key="j.id"
            @click="noteClick(d, x)"
          >
            <CommunityNoteItem :info="j">
              <view class="index-data-like" @click.stop="likeClick(j.id)">
                <CommunityNoteLike
                  :text="j.like_count_str"
                  :isLike="myDataLikeList.includes(j.id)"
                />
              </view>
            </CommunityNoteItem>
            <view
              class="index-data-state"
              v-if="!queryData.uid && j.status !== 1"
              :style="{
                background:
                  j.status === 0
                    ? 'linear-gradient(90deg, #67d752, #1db476)'
                    : 'linear-gradient(90deg, #f1975f, #ec5556)',
              }"
            >
              {{ j.status === 0 ? "未审核" : "不通过" }}
            </view>
          </view>
        </view>
      </view>
      <ListMore v-if="listLoadMore" :status="listStatus" />
    </template>

    <view class="index-data-add" v-if="!queryData.uid" @click="noteClick(-1)">
      <CommunityNoteBtn />
    </view>
  </view>

  <CommunityNotePicker ref="communityNotePicker" />
</template>

<style lang="scss">
page {
  padding-top: 130rpx;
  padding-bottom: calc(160rpx + env(safe-area-inset-bottom));
}

.index-bg {
  position: relative;

  .index-bg-img {
    display: block;
    width: 100vw;
    height: 350rpx;
    filter: blur(30rpx);
  }

  .index-bg-cover {
    position: absolute;
    left: 0;
    top: 0;
    right: 0;
    bottom: 0;
    background-color: rgba(0, 0, 0, 0.1);
  }
}

.index-info {
  position: relative;
  padding-top: 114rpx;
  padding-bottom: 40rpx;
  margin-bottom: 20rpx;
  border-radius: 40rpx 40rpx 0 0;
  background-color: #ffffff;

  .index-info-avatar {
    position: absolute;
    left: 50%;
    top: -100rpx;
    width: 178rpx;
    height: 178rpx;
    border-radius: 50%;
    border: 8rpx solid #fefefe;
    transform: translateX(-50%);
  }

  .index-info-name {
    margin: 0 90rpx 10rpx;
    font-size: 40rpx;
    color: #333333;
    line-height: 56rpx;
    text-align: center;
    font-weight: bold;
  }

  .index-info-intro {
    position: relative;
    max-height: 68rpx;
    margin: 0 90rpx 40rpx;
  }

  .index-info-intro2 {
    font-size: 24rpx;
    color: #999999;
    line-height: 34rpx;
    text-align: center;
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 2;
    text-overflow: ellipsis;
    overflow: hidden;
  }

  .index-info-intro3 {
    position: absolute;
    right: -38rpx;
    bottom: 4rpx;
    width: 28rpx;
    height: 28rpx;
  }

  .index-info-item {
    width: 128rpx;
    margin: 0 40rpx;
  }

  .index-info-num {
    font-size: 32rpx;
    color: #333333;
    line-height: 44rpx;
    text-align: center;
    font-weight: bold;
  }

  .index-info-text {
    font-size: 24rpx;
    color: #999999;
    line-height: 34rpx;
    text-align: center;
  }

  .index-info-follow {
    position: absolute;
    top: -76rpx;
    right: 30rpx;
    width: 160rpx;
    font-size: 28rpx;
    color: #ffffff;
    line-height: 56rpx;
    text-align: center;
    border-radius: 28rpx;
    background-color: #fd3748;
  }
}

.index-type {
  display: flex;
  align-items: center;
  height: 88rpx;
  padding-left: 30rpx;

  .index-type-item {
    padding: 0 24rpx;
    margin-right: 40rpx;
  }
}

.index-state {
  display: flex;
  align-items: center;
  height: 80rpx;
  padding-left: 30rpx;
  border-top: 2rpx solid #eeeeee;

  .index-state-item {
    padding: 0 30rpx;
    margin-right: 10rpx;
    font-size: 28rpx;
    color: #999999;
    line-height: 60rpx;
  }

  .index-state-active {
    color: #333333;
    font-weight: bold;
  }
}

.index-data {
  .index-data-empty {
    padding-top: 160rpx;
  }

  .index-data-wrapper {
    display: flex;
    justify-content: flex-start;
    padding-left: 30rpx;
    padding-top: 10rpx;
    padding-bottom: 1rpx;
  }

  .index-data-column {
    margin-right: 18rpx;
  }

  .index-data-item {
    position: relative;
    margin-bottom: 20rpx;
  }

  .index-data-like {
    flex-shrink: 0;
    margin-left: 10rpx;
  }

  .index-data-state {
    position: absolute;
    left: 20rpx;
    top: 20rpx;
    padding: 0 16rpx;
    font-size: 20rpx;
    color: #ffffff;
    line-height: 40rpx;
    border-radius: 24rpx;
  }

  .index-data-add {
    position: fixed;
    left: 50%;
    bottom: calc(60rpx + env(safe-area-inset-bottom));
    transform: translateX(-50%);
  }
}
</style>